<html>
<head>
<link rel="shortcut icon" href="./favicon.ico">
<link rel="stylesheet" type="text/css" href="./style.css">
<link rel="canonical" href="./Counter_Binary.html">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="This counter counts by the `INCREMENT` parameter value, up or down, when `run` is high.  Set `up_down` to 0 to count up, or to 1 to count down. Load overrides counting, so you can load a `load_count` value even if `run` is low.  `clear` puts the counter back at INITIAL_COUNT.  The counter will wrap around if it goes below zero or above `(2^WORD_WIDTH)-1` and set `overflow` for that cycle.">
<title>Counter Binary</title>
</head>
<body>

<p class="inline bordered"><b><a href="./Counter_Binary.v">Source</a></b></p>
<p class="inline bordered"><b><a href="./legal.html">License</a></b></p>
<p class="inline bordered"><b><a href="./index.html">Index</a></b></p>

<h1>A Binary Up/Down Counter</h1>
<p>This counter counts by the <code>INCREMENT</code> parameter value, up or down, when
 <code>run</code> is high.  Set <code>up_down</code> to 0 to count up, or to 1 to count down.
 Load overrides counting, so you can load a <code>load_count</code> value even if <code>run</code>
 is low.  <code>clear</code> puts the counter back at INITIAL_COUNT.  The counter will
 wrap around if it goes below zero or above <code>(2^WORD_WIDTH)-1</code> and set
 <code>overflow</code> for that cycle.</p>
<p>The <code>INCREMENT</code> parameter allows you to deal with situations where, for
 example, you need to count the number of bytes transferred, but your
 interface transfers multiple bytes per cycle.</p>
<p>When chaining counters, which may happen if you are counting in unusual
 bases where each digit has its own counter, AND the <code>carry_out</code> of the
 previous counter with the signal fed to the <code>run</code> input of the next
 counter. The <code>carry_in</code> is kept for generality, as are the <code>carries</code> into
 each bit.</p>

<pre>
`default_nettype none

module <a href="./Counter_Binary.html">Counter_Binary</a>
#(
    parameter                   WORD_WIDTH      = 0,
    parameter [WORD_WIDTH-1:0]  INCREMENT       = 0,
    parameter [WORD_WIDTH-1:0]  INITIAL_COUNT   = 0
)
(
    input   wire                        clock,
    input   wire                        clear,

    input   wire                        up_down, // 0/1 --> up/down
    input   wire                        run,

    input   wire                        load,
    input   wire    [WORD_WIDTH-1:0]    load_count,

    input   wire                        carry_in,
    output  wire                        carry_out,
    output  wire    [WORD_WIDTH-1:0]    carries,
    output  wire                        overflow,

    output  wire    [WORD_WIDTH-1:0]    count
);

    localparam WORD_ZERO = {WORD_WIDTH{1'b0}};
</pre>

<p>First we calculate the next counter value using a <a href="./Adder_Subtractor_Binary.html">Binary
 Adder/Subtractor</a>. Having a dedicated
 module for this allows us to change how the counter works (e.g.: BCD or
 other counting schemes) without altering any other logic. It also hides the
 tricks needed for correct arithmetic logic inference.</p>

<pre>
    wire [WORD_WIDTH-1:0] incremented_count;
    wire                  carry_out_internal;
    wire [WORD_WIDTH-1:0] carries_internal;
    wire                  overflow_internal;

    <a href="./Adder_Subtractor_Binary.html">Adder_Subtractor_Binary</a>
    #(
        .WORD_WIDTH (WORD_WIDTH)
    )
    calc_next_count
    (
        .add_sub    (up_down), // 0/1 -> A+B/A-B
        .carry_in   (carry_in),
        .A          (count),
        .B          (INCREMENT),
        .sum        (incremented_count),
        .carry_out  (carry_out_internal),
        .carries    (carries_internal),
        .overflow   (overflow_internal)
    );
</pre>

<p>Then calculate which value to load into the counter, and when.</p>

<pre>
    reg [WORD_WIDTH-1:0]    next_count      = WORD_ZERO;
    reg                     load_counter    = 0;
    reg                     clear_counter   = 0;
    reg                     load_flags      = 0;
    reg                     clear_flags     = 0;

    always @(*) begin
        next_count      = (load  == 1'b1) ? load_count : incremented_count;
        load_counter    = (run   == 1'b1) || (load == 1'b1);
        clear_counter   = (clear == 1'b1);
        load_flags      = (run   == 1'b1);
        clear_flags     = (load  == 1'b1) || (clear == 1'b1);
    end
</pre>

<p>Finally, store the next count value and flags, using a <a href="./Register.html">Register</a>.</p>

<pre>
    <a href="./Register.html">Register</a>
    #(
        .WORD_WIDTH     (WORD_WIDTH),
        .RESET_VALUE    (INITIAL_COUNT)
    )
    count_storage
    (
        .clock          (clock),
        .clock_enable   (load_counter),
        .clear          (clear_counter),
        .data_in        (next_count),
        .data_out       (count)
    );

    <a href="./Register.html">Register</a>
    #(
        .WORD_WIDTH     (WORD_WIDTH),
        .RESET_VALUE    (WORD_ZERO)
    )
    carries_storage
    (
        .clock          (clock),
        .clock_enable   (load_flags),
        .clear          (clear_flags),
        .data_in        (carries_internal),
        .data_out       (carries)
    );

    <a href="./Register.html">Register</a>
    #(
        .WORD_WIDTH     (1),
        .RESET_VALUE    (1'b0)
    )
    carry_out_storage
    (
        .clock          (clock),
        .clock_enable   (load_flags),
        .clear          (clear_flags),
        .data_in        (carry_out_internal),
        .data_out       (carry_out)
    );

    <a href="./Register.html">Register</a>
    #(
        .WORD_WIDTH     (1),
        .RESET_VALUE    (1'b0)
    )
    overflow_storage
    (
        .clock          (clock),
        .clock_enable   (load_flags),
        .clear          (clear_flags),
        .data_in        (overflow_internal),
        .data_out       (overflow)
    );

endmodule
</pre>

<hr>
<p><a href="./index.html">Back to FPGA Design Elements</a>
<center><a href="https://fpgacpu.ca/">fpgacpu.ca</a></center>
</body>
</html>

